inspector: Avoid grabs for inspecting
authorMatthias Clasen <mclasen@redhat.com>
Sun, 24 Feb 2019 04:06:00 +0000 (23:06 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 24 Feb 2019 14:41:13 +0000 (09:41 -0500)
Instead of using a grab on a GtkInvisible, use
a hook in the GTK event propagation machinery to
get events.

The only downside of this approach is that we
lose the crosshair cursor. But we get rid of
the last use of GtkInvisible.

gtk/gtkmain.c
gtk/inspector/inspect-button.c
gtk/inspector/window.c
gtk/inspector/window.h

index eb60808d784e70de5ef21f70f6a083ae04a50347..8aa278e9eb4f164a1872d6d5763ac0e6a579eae6 100644 (file)
 #include "gtkroot.h"
 
 #include "a11y/gtkaccessibility.h"
+#include "inspector/window.h"
 
 static GtkWindowGroup *gtk_main_get_window_group (GtkWidget   *widget);
 
@@ -1730,6 +1731,9 @@ gtk_main_do_event (GdkEvent *event)
   GdkDevice *device;
   GList *tmp_list;
 
+  if (gtk_inspector_handle_event (event))
+    return;
+
   /* Find the widget which got the event. We store the widget
    * in the user_data field of GdkSurface's. Ignore the event
    * if we don't have a widget for it.
index 6b28299e8ef7ced5ec653b9a65b77e3f258535bb..d34629d163020d6f29c04f2f33844923ca084dcd 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "gtkstack.h"
 #include "gtkmain.h"
-#include "gtkinvisibleprivate.h"
 #include "gtkwidgetprivate.h"
 #include "gtkgesturemultipress.h"
 #include "gtkeventcontrollermotion.h"
@@ -95,9 +94,8 @@ select_widget (GtkInspectorWindow *iw,
 }
 
 static void
-on_inspect_widget (GtkWidget          *button,
-                   GdkEvent           *event,
-                   GtkInspectorWindow *iw)
+on_inspect_widget (GtkInspectorWindow *iw,
+                   GdkEvent           *event)
 {
   GtkWidget *widget;
 
@@ -179,126 +177,69 @@ reemphasize_window (GtkWidget *window)
     gdk_surface_raise (gtk_widget_get_surface (window));
 }
 
+static gboolean handle_event (GtkInspectorWindow *iw, GdkEvent *event);
+
 static void
-property_query_pressed (GtkGestureMultiPress *gesture,
-                        guint                 n_press,
-                        gdouble               x,
-                        gdouble               y,
-                        GtkInspectorWindow   *iw)
+handle_button_event (GtkInspectorWindow *iw,
+                     GdkEvent           *event)
 {
-  GdkEvent *event;
-
-  gtk_grab_remove (iw->invisible);
-  if (iw->grab_seat)
-    {
-      gdk_seat_ungrab (iw->grab_seat);
-      iw->grab_seat = NULL;
-    }
-
+  g_signal_handlers_disconnect_by_func (iw, handle_event, NULL);
   reemphasize_window (GTK_WIDGET (iw));
+  on_inspect_widget (iw, event);
+}
 
-  event = gtk_get_current_event ();
-  on_inspect_widget (iw->invisible, event, iw);
-  g_object_unref (event);
-
-  gtk_widget_destroy (iw->invisible);
-  iw->invisible = NULL;
+static void
+handle_motion_event (GtkInspectorWindow *iw,
+                     GdkEvent           *event)
+{
+  on_highlight_widget (NULL, event, iw);
 }
 
 static void
-property_query_motion (GtkEventControllerMotion *controller,
-                       gdouble                   x,
-                       gdouble                   y,
-                       GtkInspectorWindow       *iw)
+handle_key_event (GtkInspectorWindow *iw,
+                  GdkEvent           *event)
 {
-  GdkEvent *event;
+  guint keyval = 0;
 
-  event = gtk_get_current_event ();
-  on_highlight_widget (iw->invisible, event, iw);
-  g_object_unref (event);
+  gdk_event_get_keyval (event, &keyval);
+  if (keyval == GDK_KEY_Escape)
+    {
+      g_signal_handlers_disconnect_by_func (iw, handle_event, NULL);
+      reemphasize_window (GTK_WIDGET (iw));
+      clear_flash (iw);
+    }
 }
 
 static gboolean
-property_query_key (GtkEventControllerKey *key,
-                    guint                  keyval,
-                    guint                  keycode,
-                    GdkModifierType        modifiers,
-                    GtkInspectorWindow    *iw)
+handle_event (GtkInspectorWindow *iw, GdkEvent *event)
 {
-  if (keyval == GDK_KEY_Escape)
+  switch ((int)gdk_event_get_event_type (event))
     {
-      gtk_grab_remove (iw->invisible);
-      if (iw->grab_seat)
-        {
-          gdk_seat_ungrab (iw->grab_seat);
-          iw->grab_seat = NULL;
-        }
-      reemphasize_window (GTK_WIDGET (iw));
+    case GDK_KEY_PRESS:
+    case GDK_KEY_RELEASE:
+      handle_key_event (iw, event);
+      break;
 
-      clear_flash (iw);
+    case GDK_MOTION_NOTIFY:
+      handle_motion_event (iw, event);
+      break;
 
-      gtk_widget_destroy (iw->invisible);
-      iw->invisible = NULL;
+    case GDK_BUTTON_PRESS:
+    case GDK_BUTTON_RELEASE:
+      handle_button_event (iw, event);
+      break;
 
-      return TRUE;
+    default:;
     }
 
-  return FALSE;
-}
-
-static void
-prepare_inspect_func (GdkSeat   *seat,
-                      GdkSurface *surface,
-                      gpointer   user_data)
-{
-  gdk_surface_show (surface);
+  return TRUE;
 }
 
-
 void
 gtk_inspector_on_inspect (GtkWidget          *button,
                           GtkInspectorWindow *iw)
 {
-  GdkDisplay *display;
-  GdkCursor *cursor;
-  GdkGrabStatus status;
-  GtkEventController *controller;
-  GdkSeat *seat;
-
-  if (!iw->invisible)
-    {
-      iw->invisible = gtk_invisible_new_for_display (gdk_display_get_default ());
-      gtk_widget_realize (iw->invisible);
-      gtk_widget_show (iw->invisible);
-    }
-
-  display = gdk_display_get_default ();
-  cursor = gdk_cursor_new_from_name ("crosshair", NULL);
-  seat = gdk_display_get_default_seat (display);
-  status = gdk_seat_grab (seat,
-                          gtk_widget_get_surface (iw->invisible),
-                          GDK_SEAT_CAPABILITY_ALL_POINTING, TRUE,
-                          cursor, NULL, prepare_inspect_func, NULL);
-  g_object_unref (cursor);
-  if (status == GDK_GRAB_SUCCESS)
-    iw->grab_seat = seat;
-
-  controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
-  g_signal_connect (controller, "pressed",
-                   G_CALLBACK (property_query_pressed), iw);
-  gtk_widget_add_controller (iw->invisible, controller);
-
-  controller = gtk_event_controller_motion_new ();
-  g_signal_connect (controller, "motion",
-                    G_CALLBACK (property_query_motion), iw);
-  gtk_widget_add_controller (iw->invisible, controller);
-
-  controller = GTK_EVENT_CONTROLLER (gtk_event_controller_key_new ());
-  g_signal_connect (controller, "key-pressed",
-                    G_CALLBACK (property_query_key), iw);
-  gtk_widget_add_controller (iw->invisible, controller);
-
-  gtk_grab_add (GTK_WIDGET (iw->invisible));
+  g_signal_connect (iw, "event", G_CALLBACK (handle_event), NULL);
   deemphasize_window (GTK_WIDGET (iw));
 }
 
index 9bdced31e416d183ea8a85ae6b38ecb4666f6c63..191bbb90b3f23e29ebe261bb94fb185269693984 100644 (file)
@@ -286,6 +286,17 @@ gtk_inspector_window_class_init (GtkInspectorWindowClass *klass)
   object_class->constructed = gtk_inspector_window_constructed;
   widget_class->realize = gtk_inspector_window_realize;
 
+  g_signal_new (g_intern_static_string ("event"),
+                G_OBJECT_CLASS_TYPE (object_class),
+                G_SIGNAL_RUN_LAST,
+                0,
+                g_signal_accumulator_true_handled,
+                NULL,
+                NULL,
+                G_TYPE_BOOLEAN,
+                1,
+                GDK_TYPE_EVENT);
+
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/window.ui");
 
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, top_stack);
@@ -468,4 +479,19 @@ gtk_inspector_is_recording (GtkWidget *widget)
   return gtk_inspector_recorder_is_recording (GTK_INSPECTOR_RECORDER (iw->widget_recorder));
 }
 
+gboolean
+gtk_inspector_handle_event (GdkEvent *event)
+{
+  GtkInspectorWindow *iw;
+  gboolean handled = FALSE;
+
+  iw = gtk_inspector_window_get_for_display (gdk_event_get_display (event));
+  if (iw == NULL)
+    return FALSE;
+
+  g_signal_emit_by_name (iw, "event", event, &handled);
+
+  return handled;
+}
+
 // vim: set et sw=2 ts=2:
index ed1adfa3dfaaadc1cbc10bfc42312701be2b7f13..6e3c5f6647b0ea4b39dda19fd01d2f8a78da8872 100644 (file)
@@ -72,7 +72,6 @@ typedef struct
   GtkWidget *controllers;
   GtkWidget *magnifier;
 
-  GtkWidget *invisible;
   GtkWidget *selected_widget;
 
   GList *extra_pages;
@@ -117,6 +116,8 @@ GskRenderNode *         gtk_inspector_prepare_render
                                                                                  GdkSurface             *surface,
                                                                                  const cairo_region_t   *region,
                                                                                  GskRenderNode          *node);
+gboolean                gtk_inspector_handle_event                              (GdkEvent               *event);
+                                                                                
 
 G_END_DECLS